home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / JCurrencyTextField.java < prev    next >
Text File  |  1998-09-08  |  10KB  |  283 lines

  1. package com.symantec.itools.swing;
  2.  
  3. import java.awt.event.KeyEvent;
  4. import java.awt.event.KeyAdapter;
  5. import java.awt.event.FocusEvent;
  6. import java.awt.event.FocusAdapter;
  7. import java.awt.datatransfer.*;
  8. import com.sun.java.swing.text.Document;
  9. import com.sun.java.swing.text.PlainDocument;
  10. import com.sun.java.swing.event.DocumentListener;
  11. import com.sun.java.swing.event.DocumentEvent;
  12.  
  13. public class JCurrencyTextField extends com.sun.java.swing.JTextField {
  14.     public JCurrencyTextField(                   ) { this(""         , 0              );    }
  15.     public JCurrencyTextField(int numberOfColumns) { this(""         , numberOfColumns); }
  16.     public JCurrencyTextField(String  initialText) { this(initialText, 256            ); }
  17.     public JCurrencyTextField(String initialText, int numberOfColumns)    {
  18.         this(null, initialText, numberOfColumns);
  19.     }
  20.  
  21.   // All other constructors call this one.
  22.     public JCurrencyTextField(Document doc, String initialText, int numberOfColumns)    {
  23.         super(doc, initialText, numberOfColumns);
  24.         setHorizontalAlignment(RIGHT);
  25.     }
  26.  
  27.   public synchronized void setFormattedText(String data) {
  28.       StringBuffer s = new StringBuffer();
  29.       _dataText = data;
  30.       int pos = _engine.initDisplay(data, s);
  31.       if (!_haveFocus) {
  32.         StringBuffer newData = new StringBuffer();
  33.         _engine.postFormat(s.toString(), newData);
  34.         s = newData;
  35.         _isFormatted = true;
  36.         if (_focusListener == null) {
  37.           setText(s.toString());
  38.           return;  // don't call peer if it doesn't exist yet
  39.         }
  40.       }
  41.       setText(s.toString());
  42.       if (_haveFocus) {
  43.         setCaretPosition(pos);
  44.         if (data.length() == 0 && !_engine.getATMmode())
  45.           select(0, s.length());
  46.         _isFormatted = false;
  47.       }
  48.   }
  49.  
  50.   public synchronized void format() {
  51.       StringBuffer newData = new StringBuffer();
  52.       _engine.postFormat(getDataText(), newData);
  53.       setText(newData.toString());
  54.       _isFormatted = true;
  55.   }
  56.  
  57.   public synchronized String getDataText() {
  58.       if (_dataText == null)
  59.         _dataText = getText();
  60.       return _dataText;
  61.   }
  62.  
  63.   //  Get/Set properties: all are properties of the currency engine
  64.   public boolean isCurrencyLeading    (         ) { return _engine.getCurrencyLeading   ( ); }
  65.   public boolean isSeparatorEnabled   (         ) { return _engine.getCommas            ( ); }
  66.   public boolean getATMmode           (         ) { return _engine.getATMmode           ( ); }
  67.   public String  getCurrencySymbol    (         ) { return _engine.getCurrencySymbol    ( ); }
  68.   public char    getDecimalPoint      (         ) { return _engine.getDecimalPoint      ( ); }
  69.   public char    getSeparator         (         ) { return _engine.getSeparator         ( ); }
  70.   public int     getDigitsAfterDecimal(         ) { return _engine.getDigitsAfterDecimal( ); }
  71.   public void    setCurrencyLeading   (boolean b) {        _engine.setCurrencyLeading   (b); }
  72.   public void    setSeparatorEnabled  (boolean b) {        _engine.setCommas            (b); }
  73.   public void    setATMmode           (boolean b) {        _engine.setATMmode           (b); }
  74.   public void    setCurrencySymbol    (String  s) {        _engine.setCurrencySymbol    (s); }
  75.   public void    setDecimalPoint      (char    c) {        _engine.setDecimalPoint      (c); }
  76.   public void    setSeparator         (char    c) {        _engine.setSeparator         (c); }
  77.   public void    setDigitsAfterDecimal(int     n) {        _engine.setDigitsAfterDecimal(n); }
  78.  
  79.   public synchronized void cut(Clipboard clipboard) {
  80.       _activity = true;
  81.       String s = getText();
  82.       int selStart = getSelectionStart();
  83.       int selEnd = getSelectionEnd();
  84.       StringSelection ss = new StringSelection(s.substring(selStart, selEnd));
  85.       clipboard.setContents(ss, ss);
  86.       StringBuffer newData = new StringBuffer(s);
  87.       _engine.cut(newData, selStart, selEnd);
  88.       setText(newData.toString());
  89.       select(0,0);
  90.       setCaretPosition(selStart);
  91.   }
  92.  
  93.   public synchronized void paste(Clipboard clipboard) {
  94.       _activity = true;
  95.       String pasteData = "";
  96.       try {
  97.         pasteData = (String)clipboard.getContents(this).getTransferData(DataFlavor.stringFlavor);
  98.       } catch (Exception e) {}
  99.       int selStart = getSelectionStart();
  100.       int selEnd   = getSelectionEnd();
  101.       int pos      = getCaretPosition();
  102.       StringBuffer data = new StringBuffer(getText());
  103.       _engine.paste(data, pasteData, pos, selStart, selEnd);
  104.       setText(data.toString());
  105.       select(0,0);
  106.       setCaretPosition(pos);
  107.   }
  108.  
  109.   // Override of JTextComponent
  110.   public void cut() {
  111.     cut(java.awt.Toolkit.getDefaultToolkit().getSystemClipboard());
  112.   }
  113.  
  114.   // Override of JTextComponent
  115.   public void paste() {
  116.     paste(java.awt.Toolkit.getDefaultToolkit().getSystemClipboard());
  117.   }
  118.  
  119.  
  120.   /**
  121.    * This is a standard AWT method which gets called when
  122.    * this component is added to a container.
  123.    *
  124.    * @see #removeNotify
  125.    */
  126.   public synchronized void addNotify() {
  127.     if (_focusListener == null) {
  128.       _focusListener = new FocusAdapter() {
  129.         public void focusGained(FocusEvent e) { gotFocus (e); }
  130.         public void focusLost  (FocusEvent e) { lostFocus(e); }
  131.       };
  132.       addFocusListener(_focusListener);
  133.     }
  134.     super.addNotify();
  135.   }
  136.  
  137.   /**
  138.    * This method gets called when this component is removed from a
  139.    * container. Typically, it is used to destroy the peers of this
  140.    * component and all its subcomponents.
  141.    * It has been overridden here to call removeKeyListener.
  142.    *
  143.    * @see #addNotify
  144.    */
  145.   public synchronized void removeNotify() {
  146.     if (_focusListener != null) {
  147.         removeFocusListener(_focusListener);
  148.         _focusListener = null;
  149.     }
  150.     super.removeNotify();
  151.   }
  152.  
  153.   void gotFocus(FocusEvent e) {
  154.     _activity = false;
  155.     _haveFocus = true;
  156.     if (_isFormatted || getText().length() == 0)
  157.       setFormattedText(getDataText());
  158.     _dataText = null;
  159.   }
  160.  
  161.   void lostFocus(FocusEvent e) {
  162.     format();
  163.     _haveFocus = false;
  164.     if (isEditable() && _activity) {
  165.       try {
  166.         _docListenerDisabled = true;
  167.         _document.remove(0, _document.getLength());
  168.         _document.insertString(0, _dataText, null);
  169.       } catch (com.sun.java.swing.text.BadLocationException ex) {
  170.         badLocException();
  171.       } finally {
  172.         _docListenerDisabled = false;
  173.       }
  174.     }
  175.   }
  176.  
  177.   // Override JTextComponent
  178.   protected void processComponentKeyEvent(KeyEvent e) {
  179.     switch(e.getID()) {
  180.     case KeyEvent.KEY_TYPED:
  181.       e.consume();  // prevents super component from writing
  182.       break;
  183.     case KeyEvent.KEY_PRESSED:
  184.       if (_engine.isHandledKey(e) && isEditable()) {
  185.         if (_keyPressed)   // key must be auto-repeating
  186.           processKey(e);   // so process it
  187.         else {
  188.           e.consume();
  189.           _keyPressed = true;  // in case auto-repeat happens
  190.         }
  191.       } else
  192.         super.processComponentKeyEvent(e);
  193.         break;
  194.     case KeyEvent.KEY_RELEASED:
  195.       if (_engine.isHandledKey(e) && isEditable()) {
  196.         _keyPressed = false;
  197.         processKey(e);
  198.       } else
  199.         super.processComponentKeyEvent(e);
  200.       break;
  201.     }
  202.   }
  203.  
  204.   void processKey(KeyEvent e) {
  205.     _activity = true;
  206.     e.consume();
  207.     int pos = getCaretPosition();
  208.     StringBuffer newData = new StringBuffer("");
  209.     StringBuffer data = new StringBuffer(getText());
  210.     int selStart = getSelectionStart();
  211.     int selEnd = getSelectionEnd();
  212.     int newpos = _engine.processKey(e, pos, data.toString(), newData, selStart, selEnd);
  213.     if (newpos >= 0) {            // if good new caret position
  214.       setText(newData.toString());
  215.       select(0, 0);   // remove text selection, if any
  216.       setCaretPosition(newpos);
  217.     } else if (newpos == -1)
  218.       setCaretPosition(pos);
  219.   }
  220.  
  221.   // Override
  222.   // This gets called during superclass construction!
  223.   public void setDocument(Document d) {
  224.     if (_docListener == null)
  225.       _docListener = new DocumentListener() {
  226.         public void changedUpdate(DocumentEvent e) { docChange(e); }
  227.         public void removeUpdate (DocumentEvent e) { docRemove(e); }
  228.         public void insertUpdate (DocumentEvent e) { docInsert(e); }
  229.       };
  230.  
  231.     if (_document != null)
  232.       _document.removeDocumentListener(_docListener);
  233.     _document = d;
  234.     _document.addDocumentListener(_docListener);
  235.     if (_myDoc == null)
  236.       _myDoc = new PlainDocument();
  237.     super.setDocument(_myDoc);
  238.   }
  239.  
  240.   // This shouldn't get called except by this class
  241.   protected void docChange(DocumentEvent e) {
  242.     if (_docListenerDisabled)
  243.       return;
  244. //    System.out.println("Currency Doc Listener Change Called");
  245.   }
  246.  
  247.   protected void docRemove(DocumentEvent e) {
  248.     if (_docListenerDisabled)
  249.       return;
  250.     setText(_dataText = "");
  251.   }
  252.  
  253.   // This gets called on data insertion into the field
  254.   protected void docInsert(DocumentEvent e) {
  255.     if (_docListenerDisabled)
  256.       return;
  257.     int len = e.getLength();
  258.     String data = "";
  259.     try {
  260.       data = _document.getText(0, len);
  261.     } catch(com.sun.java.swing.text.BadLocationException ex) {
  262.       badLocException();
  263.     }
  264.     setFormattedText(data);
  265.   }
  266.  
  267.   protected void badLocException() {
  268.     getToolkit().beep();
  269.     System.out.println("Bad Location Exception in JCurrencyTextField");
  270.   }
  271.  
  272.   private PlainDocument    _myDoc         = null;
  273.   private DocumentListener _docListener   = null;
  274.   private Document         _document      = null;
  275.   private boolean          _docListenerDisabled = false;
  276.   private CurrencyEngine   _engine        = new CurrencyEngine();
  277.      private FocusAdapter     _focusListener = null;
  278.   private String           _dataText      = null;
  279.   private boolean          _haveFocus     = false;
  280.   private boolean          _isFormatted   = false;
  281.     private boolean          _keyPressed    = false;   // true if a key is down
  282.     private boolean          _activity      = false;
  283. }